#ifndef __SPINLOCK_H__
#define __SPINLOCK_H__

// routines from /usr/src/linux/include/asm-ppc/spinlock.h

static __inline__ void spin_lock (volatile int* lock) {
    char oldval;
    __asm__ __volatile__
        (
         "\n1:\t" \
         "cmpb $0,%1\n\t" \
         "jne 1b\n\t" \
         "xchgb %b0, %1\n\t" \
         "cmpb $0,%0\n" \
         "jne 1b\n\t"
         :"=q"(oldval), "=m"(*lock)
         : "0"(1)
         : "memory");
}

static __inline__ void spin_unlock (volatile int* lock) {
	__asm__ __volatile__
        ("movb $0,%0" \
         :"=m" (*lock) : : "memory");
}

static __inline__ int trylock (volatile int* lock) {
    char oldval;
    __asm__ __volatile__
        (
         "xchgb %b0,%1"
         :"=q" (oldval),
          "=m" (*lock)
         :"0" (1) 
         : "memory");
    return oldval == 0;
}

#endif  // __SPINLOCK_H__
